using System;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Resources;
using Microsoft.Phone.BackgroundAudio;
using NetworkInterface = System.Net.NetworkInformation.NetworkInterface;

namespace DeepMixWorkflow
{
    public static class CommonHelper
    {
        private const string LogFileName = @"log.txt";

#if BETA
        private static string _log = String.Empty;
#endif

        /// <summary>
        /// Extract Artist Name and Track Name from Title
        /// groups: artist, track
        /// </summary>
        public static Regex TrackTitleRegex = new Regex(@"\A(?<artist>.+): (?<track>.+)\z", RegexOptions.Compiled);

        static CommonHelper()
        {
            if (!StorageContainer.ErrorSound.Exists)
            {
                StreamResourceInfo resource = Application.GetResourceStream(new Uri("error.wma", UriKind.Relative));
                StorageContainer.ErrorSound.DoWriteNew(stream =>
                    {
                        const int chunkSize = 4096;
                        var bytes = new byte[chunkSize];
                        int byteCount;

                        while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
                        {
                            stream.Write(bytes, 0, byteCount);
                        }
                    });
            }
        }

        private static void LoadFromUri(string uri, Action<string> onFinish, Action<Exception> onError = null)
        {
            var client = new WebClient {AllowReadStreamBuffering = true};

            client.OpenReadCompleted += (sender, args) =>
                {
                    if (args.Error == null)
                    {
                        try
                        {
                            using (var reader = new StreamReader(args.Result))
                            {
                                string result = reader.ReadToEnd();
                                onFinish(result);
                            }
                        }
                        catch (WebException)
                        {
                            if (onError != null) onError(args.Error);
                        }
                    }
                    else
                    {
                        if (onError != null) onError(args.Error);
                    }
                };

            client.OpenReadAsync(new Uri(uri));
        }


        public static void GetSelected(Action<DeepMixTrack[]> onFinish, Action<Exception> onError = null)
        {
            if (onFinish == null) throw new ArgumentNullException("onFinish");

            LoadFromUri(@"http://mobile.deepmix.ru/select-pda.php", result =>
                {
                    var parser = new SelectedMusicParser(result);
                    DeepMixTrack[] tracks = parser.GetSelectedTracks().ToArray();
                    onFinish(tracks);
                }, onError);
        }

        public static void GetNowPlayingParser(Action<NowPlayingParser> onFinish, Action<Exception> onError)
        {
            LoadFromUri(@"http://deepmix.eu/", result =>
                {
                    var parser = new NowPlayingParser(result);
                    onFinish(parser);
                }, onError);
        }

        public static void GetNowPlayingTrack(Action<DeepMixTrack> onFinish, Action<Exception> onError = null)
        {
            if (onFinish == null) throw new ArgumentNullException("onFinish");

            GetNowPlayingParser(result => onFinish(result.GetNowPlayingTrack()), onError);
        }

        public static bool IsOnline()
        {
#if DEBUG
            return false;
#else
            return NetworkInterface.GetIsNetworkAvailable();
#endif
        }

        public static DeepMixTrack FromAudioTrack(AudioTrack audioTrack)
        {
            string uri;
            audioTrack.Tag.GetDeepMixMode(out uri);
            return new DeepMixTrack {Artist = audioTrack.Artist, Link = uri, Title = audioTrack.Title};
        }

        public static string AboutTrack(this AudioTrack track)
        {
            return
                String.Format(
                    "Album: {0}, Artist: {1}, Duration: {2}, Controls: {3}, Source: {4}, Tag: {5}, Title: {6}",
                    track.Album, track.Artist, "null", track.PlayerControls, track.Source,
                    track.Tag, track.Title);
        }

        public static void SayErrcommor()
        {
            BackgroundAudioPlayer.Instance.Track = new AudioTrack(new Uri(StorageContainer.ErrorSound.FileName, UriKind.Relative), String.Empty,
                                                                  String.Empty, null, null, TagParser.CreateError(),
                                                                  EnabledPlayerControls.None);
        }

        public static void Log(string str, params object[] pars)
        {
#if DEBUG || BETA
            string message = String.Format(str, pars);


            Debug.WriteLine(message);
#endif

#if BETA
    // _log += string.Format(message + ": {0}", DateTime.Now)+@"
//";
            lock(_isoLocker)
            {
                using (var store = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    using(var stream = store.OpenFile(_logFileName, FileMode.Append))
                    {
                        var streamWriter = new StreamWriter(stream);
                        streamWriter.WriteLine(string.Format(message+": {0}",DateTime.Now));
                        streamWriter.Flush();
                        stream.Close();
                    }
                }
            }
#endif
        }

// ReSharper disable UnusedMember.Local
// ReSharper restore UnusedMember.Local

        public static string SendLog()
        {
            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (store.FileExists(LogFileName))
                {
                    IsolatedStorageFileStream stream = store.OpenFile(LogFileName, FileMode.Open);
                    stream.Position = 0;
                    var reader = new StreamReader(stream);
                    string log = reader.ReadToEnd();
                    stream.Close();
                    store.DeleteFile(LogFileName);
                    return log;
                }
                return String.Empty;
            }
        }

        public static DeepMixTrack ParseTrackName(string str)
        {
            Match match = TrackTitleRegex.Match(str.Trim());
            return new DeepMixTrack {Title = match.Groups["track"].Value, Artist = match.Groups["artist"].Value};
        }
    }
}